/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.solarchallenge.client.gwtui.widgets.uploadonefile;

import static com.google.solarchallenge.client.rpc.ServiceProvider.getServiceProvider;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.solarchallenge.client.gwtui.mvpinterfaces.Display;
import com.google.solarchallenge.client.gwtui.mvpinterfaces.View;
import com.google.solarchallenge.client.gwtui.widgets.solarchallengeheaderbar.SolarChallengeHeaderBarDisplay;
import com.google.solarchallenge.client.rpc.ServiceProvider;
import com.google.solarchallenge.shared.ApplicationDocumentCategory;
import com.google.solarchallenge.shared.FileUploadStatus;

/**
 * View for UploadOneFile Widget.
 *
 * @author Arjun Satyapal
 */
public class UploadOneFileView extends View implements UploadOneFileDisplay {
  @UiField
  FileUpload fileUpload;
  @UiField
  Button buttonUpload;
  @UiField
  FormPanel formPanel;
  @UiField
  Label labelStatus;

  private boolean isSetHandler = false;

  private static UploadOneFileViewUiBinder uiBinder = GWT
      .create(UploadOneFileViewUiBinder.class);

  interface UploadOneFileViewUiBinder extends
      UiBinder<Widget, UploadOneFileView> {
  }

  public UploadOneFileView() {
    initWidget(uiBinder.createAndBindUi(this));
    formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
    formPanel.setMethod(FormPanel.METHOD_POST);

    fileUpload.addChangeHandler(new ChangeHandler() {
      @Override
      public void onChange(ChangeEvent event) {
        labelStatus.setText(FileUploadStatus.PENDING.getStatus());
      }
    });
  }

  @Override
  public SolarChallengeHeaderBarDisplay getSolarChallengeHeaderPanel() {
    return null;
  }

  @Override
  public void setEnabled(boolean enabled) {
    fileUpload.setEnabled(enabled);
    buttonUpload.setEnabled(enabled);
  }

  @Override
  public FileUpload getFileUpload() {
    return fileUpload;
  }

  @Override
  public Button getButtonUpload() {
    return buttonUpload;
  }

  @Override
  public void uploadToUrl(String uploadUrl,
      ApplicationDocumentCategory documentCategory, String applicationId,
      Display display, @SuppressWarnings("rawtypes")
      AsyncCallback parentCallback) {
    fileUpload.setName(documentCategory.getFileUploadName());
    formPanel.setAction(uploadUrl);
    if (!isSetHandler) {
      isSetHandler = true;
      formPanel.addSubmitCompleteHandler(getSubmitCompleteHandlerForNotes(
          documentCategory, applicationId, uploadUrl, display, parentCallback));
    }

    formPanel.submit();
    formPanel.reset();
    display.setEnabled(false);
  }

  private SubmitCompleteHandler getSubmitCompleteHandlerForNotes(
      final ApplicationDocumentCategory documentCategory,
      final String applicationId, final String uploadUrl,
      final Display display, @SuppressWarnings("rawtypes")
      final AsyncCallback parentCallback) {
    SubmitCompleteHandler handler = new SubmitCompleteHandler() {
      @Override
      public void onSubmitComplete(SubmitCompleteEvent event) {
        getServiceProvider().getApplicantService().storeUrlWithApplication(
            documentCategory, applicationId, uploadUrl,
            getCallbackForUpdatingUrl(applicationId, parentCallback));
        labelStatus.setText(FileUploadStatus.SUCCESS.getStatus());
        display.setEnabled(true);
      }
    };
    return handler;
  }

  private AsyncCallback<Void> getCallbackForUpdatingUrl(
      final String applicationId, @SuppressWarnings("rawtypes")
      final AsyncCallback parentCallback) {
    AsyncCallback<Void> callback = new AsyncCallback<Void>() {
      @Override
      public void onFailure(Throwable caught) {
        Window.alert("Failed to store the URL on the server.");
        labelStatus.setText(FileUploadStatus.FAILED.getStatus());
      }

      @SuppressWarnings("unchecked")
      @Override
      public void onSuccess(Void result) {
        ServiceProvider.getServiceProvider().getApplicantService()
            .getApplicationDetails(applicationId, parentCallback);
      }
    };
    return callback;
  }

  @Override
  public String validate() {
    if (fileUpload.getFilename().isEmpty()) {
      return ("Please set a file name.");
    }

    return null;
  }

  @Override
  public FormPanel getFormPanel() {
    return formPanel;
  }
}
